/**
 * 根据keyword过滤
 * 优化原版的过滤(原版使用递归效率低)
 * @param {string} keyword 搜索关键字 可以用,分割 直接多项或查询
 * @param {Array} list 要过滤的列表
 * @param {object} options 主键等配置信息
 * @returns {Array}
 */
export function keywordFilter(keyword, list, options) {
  const tmp = new Set()
  const keywords = keyword.split(/[,，]/).filter(v => v);
  list.forEach(node => {
    let has
    if (options.labelExtendKey) {
      has = keywords.some(keyword => node[options.labelKey] && node[options.labelKey].includes(keyword) || node[options.labelExtendKey] && node[options.labelExtendKey].includes(keywords));
    } else {
      has = keywords.some(keyword => node[options.labelKey] && node[options.labelKey].includes(keyword));
    }
     if (has) {
      // tmp.add(node[options.idKey]) path已包含自己
      node.path.forEach(p => tmp.add(p))
    }
  })
  return list.filter(node => tmp.has(node[options.idKey]))
}

export function extentFilter(extendFilter, list, map, options) {
  let tmp = new Set()
  // 判断是否存在 ,最外层的数组是并且关系, 对象内是或者关系
  list.forEach(node => {
    const has = extendFilter.every(kAnd => {
      const extendFilters = Object.keys(kAnd)
      return extendFilters.some(kOr => node[kOr] === kAnd[kOr])
    });
    if (has) {
      // tmp.add(node[options.idKey]) path已包含自己
      node.path.forEach(p => tmp.add(p))
    }
  })

  const res = list.filter(i => tmp.has(i[options.idKey]))
  // 再次循环 判断是否是最后一级(有子节点)
  res.forEach(item => {
    let hasChildren = false
    if (item[options.childrenKey]) {
      item[options.childrenKey].forEach(c_item => {
        tmp.has(c_item[options.idKey]) && (hasChildren = true)
      })
    }
    if (!hasChildren) {
      item.isLeaf = true
    }
  })

  return list.filter(i => tmp.has(i[options.idKey]))
}

export function checkedOnlyFilter(list, options) {
  const tmp = new Set()
  // 判断是否存在 ,最外层的数组是并且关系, 对象内是或者关系
  list.forEach(node => {
    const has = node.checked || node.indeterminate
    if (has) {
      node.path.forEach(p => tmp.add(p))
    }
  })
  return list.filter(i => tmp.has(i[options.idKey]))
}

/**
 * 深度优先遍历算法, 遍历tree的每一项
 * @param {Object} {tree, path: 父节点的path, init: 是否是初始化}
 * @param cb 回调函数，参数为 node
 * @param options
 */
// @ts-ignore
export function depthFirstEach({ tree, path = [], init = false, options }, cb) {
  if (!Array.isArray(tree)) {
    console.warn('The tree in the first argument to function depthFirstEach must be an array');
    return;
  }
  if (!tree || tree.length === 0) return;
  for (let node of tree) {
    const hasChildren = node[options.childrenKey] && node[options.childrenKey].length > 0;
    if (init) {
      node.path = [...path, node[options.idKey]];
      node.isLeaf = !hasChildren;
    }
    if (cb) {
      const res = cb(node);
      if (res === 'break') return;
    }
    if (hasChildren) {
      depthFirstEach({ tree: node.children, path: node.path, init, options }, cb);
    }
  }
}

/**
 * 转换
 * @param filterList
 * @param options
 * @returns {undefined|*[]}
 */
export function listToTree(filterList, options) {
  if (!Array.isArray(filterList)) {
    console.warn('The parameter filterList to function listToTree must be an array');
    return;
  }
  if (!filterList || filterList.length === 0) return [];
  let root = {
    // 0: {
    //   id: 0,
    //   lalbel: '333',
    //   childrenMap: {
    //     1: {id: 1, label: '', childrenMap: {}},
    //     2: {}
    //   }
    // },
  };
  // 定义查找父节点的函数，根据 path
  // @ts-ignore
  const parentNode = (root, path) => {
    const _path = path.slice();
    const rootId = _path.shift();
    if (_path.length > 1) {
      return parentNode(root[rootId].childrenMap, _path);
    }
    if (_path.length === 1) {
      return root[rootId].childrenMap;
    }
    return root;
  };
  // 设置filter后的 children
  const setChildren = (root) => {
    const nodes = Object.values(root);
    for (let node of nodes) {
      node[options.childrenKey] = Object.values(node.childrenMap);
      if (node[options.childrenKey] && node[options.childrenKey].length > 0) {
        setChildren(node.childrenMap);
      }
    }
  };

  filterList.forEach(node => {
    node.childrenMap = {};
    parentNode(root, node.path)[node[options.idKey]] = node;
  });
  setChildren(root);
  return Object.values(root);
}

/**
 * 广度优先遍历算法，
 * @param {Object} {tree, limitDeep: 限制遍历的深度， deep: 当前深度}
 * @param cb
 */
// @ts-ignore
export function breadthFirstEach({ tree, limitDeep = Number.MAX_SAFE_INTEGER, deep = 0, options }, cb) {
  if (!Array.isArray(tree)) {
    console.warn('The tree in the first argument to function breadthFirstEach must be an array');
    return;
  }
  if (!tree || tree.length === 0) return;
  tree.forEach(node => {
    if (cb) cb(node);
  });
  const childrenList = tree
    .filter(node => node[options.childrenKey])
    .map(i => i[options.childrenKey])
    .flat(1);
  breadthFirstEach({ tree: childrenList, limitDeep, deep: deep++, options }, cb);
}

/**
 * 广度优先遍历算法，找子树, 不包含自己
 * @param {Array} tree 原始树，数组
 * @param {Number|String} rootId 子树根结点
 * @param options
 * @return {Object} 子树
 */
// @ts-ignore
export function findSubTree(tree, rootId, options) {
  if (!Array.isArray(tree)) {
    console.warn('The parameter tree to function breadthFirstEach must be an array');
    return;
  }
  if (!tree || tree.length === 0) return [];
  const item = tree.find(node => node[options.idKey] === rootId);
  if (item) return item[options.childrenKey] || [];
  const childrenList = tree
    .filter(node => node[options.childrenKey])
    .map(i => i[options.childrenKey])
    .flat(1);
  return findSubTree(childrenList, rootId, options);
}

/**
 * 判断节点是否是亲兄弟
 * @param {Object} node1
 * @param {Object} node2
 */
// @ts-ignore
export function isBrother(node1, node2) {
  if (!node1 || !node2) return false;
  const p1 = String(node1.path.slice(0, -1));
  const p2 = String(node2.path.slice(0, -1));
  return p1 === p2;
}

/**
 * 获取父级的id
 * @param node
 * @returns {*}
 */
export function getPid(node) {
  if (node && node.path) {
    return node.path[node.path.length - 2]
  }
}
